<template>
  <a-select
    v-bind="omit(attrs, 'options')"
    v-model="modelValue"
    :disabled="disabled"
    :fallback-option="
      props.allText ? () => ({ label: props.allText, value: '__all__' }) : false
    "
    :default-value="props.allText ? '__all__' : undefined"
    :field-names="{ label: 'label', value: 'value' }"
    :loading="loading"
    :options="internalOptions">
  </a-select>
</template>

<script setup lang="ts">
import type { SelectOption } from '@arco-design/web-vue'
import { get, omit } from 'lodash-es'

import type { PromiseFn } from '@/apis/schema/all'
import type { CloudFilterBarState } from '../types'
interface IProps {
  disabled: boolean
  state: CloudFilterBarState
  allText?: string
  options: SelectOption[] | ComputedRef<SelectOption[]>
  fn?: PromiseFn
  relatedField?: string
}
const loading = ref(false)
// const props = defineProps({
//   disabled: Boolean as PropType<boolean>,
//   state: Object as PropType<CloudFilterBarState>,
//   allText: String,
//   options: Array as PropType<SelectOption[]>,
//   fn: Function as PropType<PromiseFn>
// })
const props = withDefaults(defineProps<IProps>(), {})
const attrs = useAttrs()
// 内部options
const internalOptions = ref<SelectOption[]>([])
const modelValue = defineModel<any>('modelVal', {
  default: ''
})
const fieldNames = computed(() =>
  Object.assign({}, { label: 'label', value: 'value' }, attrs?.fieldNames || {})
)
// 构建所有选项  比如  所有区域，所有用户
const buildOptionsAndValue = (options: any[]) => {
  if (props?.allText?.trim()) {
    options.unshift({
      label: props.allText,
      value: '__all__'
    })
  }
  loading.value = false
  return options
}

const fnResult = ref() //接口获取下拉选项
watch(
  () => [props?.fn, props?.disabled, props.options, props.state],
  async (newV, oldV) => {
    let relateChange = false
    if (props.relatedField && newV && oldV) {
      const field = props.relatedField!
      relateChange =
        (newV[2] as CloudFilterBarState)[field] !==
        (oldV[2] as CloudFilterBarState)[field]
    }

    const fnState = props.relatedField
      ? {
          [props.relatedField]: get(props.state, props.relatedField)
        }
      : undefined
    let res = { list: toValue(props.options) || [] }
    if (props?.fn && !props?.disabled) {
      if (!fnResult.value || relateChange) {
        // 只在第一次或关联项改变时获取,防止反复调用接口
        fnResult.value = await props?.fn?.(fnState)
      }
      res = fnResult.value
    }

    const opts = (res?.list || []).map((item: any) => {
      const { label, value } = fieldNames.value
      return {
        label: item?.[label] ?? '',
        value: item?.[value] ?? ''
      }
    })

    if (attrs?.defaultOption) {
      opts.unshift(attrs?.defaultOption)
    }
    internalOptions.value = buildOptionsAndValue(opts)

    modelValue.value = modelValue.value ? modelValue.value : '__all__'
  },
  { deep: true, immediate: true }
)
</script>
